package org.grottarossa.ui.core.controls.document.upload;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.ResourceBundle;
import java.util.UUID;

import org.grottarossa.template.data.pojo.content.Content;
import org.grottarossa.template.drivers.components.tokens.DocumentManagementId;
import org.grottarossa.ui.core.ApplicationSession;
import org.grottarossa.ui.core.IMessageNotifier;
import org.grottarossa.ui.core.i18n.DM;

import com.vaadin.terminal.Sizeable;
import com.vaadin.ui.Upload;

/***
 * Gestisce il caricamento dei documenti sul back end
 * @author g.biasci
 *
 */
public class DocumentUploader extends Upload implements Upload.SucceededListener, Upload.FailedListener,
Upload.Receiver
{
	private IMessageNotifier m_notifier;
	private final ResourceBundle m_localizer = DM.instance().getBundle(getClass().getPackage().getName() + ".UploaderResources");;
	private DocumentManagementId m_docId;
	private ArrayList<IDocumentUploaderObserver> m_observers;
	private Hashtable<String, String> m_path = new Hashtable<String, String>();
	private final boolean m_checkin;
	private final Content m_content;
	private final ApplicationSession m_appSession;

	public DocumentUploader(ApplicationSession appSession, boolean checkin, Content content)
	{
		this.m_appSession = appSession;
		this.m_checkin = checkin;
		m_content = content;
		m_observers = new ArrayList<IDocumentUploaderObserver>();
		addListener((Upload.SucceededListener)this);
		addListener((Upload.FailedListener)this);
		setReceiver(this);
	}

	/***
	 * Imposta il gestore dei messaggi
	 * @param notifier
	 */
	public void setMessageNotifier(IMessageNotifier notifier)
	{
		m_notifier = notifier;
	}

	/***
	 * Imposta l'id del documento di riferimento
	 * @param id
	 */
	public void setDocument(DocumentManagementId id)
	{
		m_docId = id;
	}

	/***
	 * Invocato all'inizio dell'upload
	 */
	public OutputStream receiveUpload(String filename, String mimeType)
	{
		OutputStream stream = null;

		try
		{
			UUID uuid = UUID.randomUUID();
			String path = System.getProperty("java.io.tmpdir") + "\\" + uuid.toString();

			if(!m_path.containsKey(filename))
				m_path.put(filename, path);

			File pathObj = new File(path);
			pathObj.mkdir();

			FileOutputStream fos = null;

			File file = new File(path + "\\" + filename);

			stream = new FileOutputStream(file);
		}
		catch(Exception ex)
		{
			stream = null;
			m_notifier.showError(ex);
		}

		return stream;
	}

	/***
	 * Invocato quando l'upload fallisce
	 */
	public void uploadFailed(FailedEvent event)
	{
		m_notifier.showError(m_localizer.getString("uploader.messages.uploadko"));
	}

	/***
	 * Carica sul back-end il file quando termina l'upload e notifica la riuscita agli osservatori
	 */
	public void uploadSucceeded(SucceededEvent event)
	{
		try
		{
			if(!m_path.containsKey(event.getFilename()))
				throw new Exception("Path not found");

			String filePath = m_path.get(event.getFilename()) + "\\" + event.getFilename();

			if(!m_checkin)
				m_appSession.getBuilder().getDocumentManagement().uploadFile(m_docId, filePath);
			else
			{
				m_content.setFilePath(filePath);
				m_appSession.getBuilder().getDocumentManagement().checkIn(m_content);
			}

			File file = new File(filePath);
			file.delete();
			file = new File(m_path.get(event.getFilename()));
			file.delete();
			m_path.remove(event.getFilename());
		}
		catch(Exception ex)
		{
			m_notifier.showError(m_localizer.getString("uploader.messages.uploadko"));
		}

		for(IDocumentUploaderObserver o : m_observers)
		{
			o.documentUploaded(event.getFilename());
		}

		m_notifier.showInfo(m_localizer.getString("uploader.messages.uploadok"));
	}

	/***
	 * Aggiunge un osservatore
	 * @param observer
	 */
	public void addObserver(IDocumentUploaderObserver observer)
	{
		m_observers.add(observer);
	}

}